/**************************************************************
 *@ProjectName: blweibo
 *@FileName: HttpUtil.java
 *@Date: 2011-5-30
 *@Copyright: 2011 www.hrbanlv.com Inc. All rights reserved.
 **************************************************************/
package com.zhiweibo.util;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.ByteArrayBuffer;
import org.apache.http.util.EncodingUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.util.Log;

import com.zhiweibo.R;
import com.zhiweibo.models.Comment;
import com.zhiweibo.models.Count;
import com.zhiweibo.models.Message;
import com.zhiweibo.models.StaticInfo;
import com.zhiweibo.models.Topic;
import com.zhiweibo.models.UnreadNum;
import com.zhiweibo.models.User;

/**
 * The Class HttpUtil.
 * 
 * @author SunHaibin
 * @since Android 1.6
 * @history 2011-5-30
 */
public class HttpUtil {

    /** The Constant lock. */
    public static final Object lock = new Object();

    /** The Constant NO_NET. */
    public static final String NO_NET = "com.hbr.weibo.nonet";

    /**
     * Login.
     * 
     * @param uname
     *            the uname
     * @param password
     *            the password
     * @return true, if successful
     */
    public static boolean login(String uname, String password) {
        try {
            URL url = new URL(Constant.VERIFY);
            String authorization = (new BASE64Encoder()).encode((uname + ":" + password).getBytes());
            URLConnection con = url.openConnection();
            con.addRequestProperty("mtype", "Android");
            con.addRequestProperty("Authorization", "BASIC: " + authorization);
            InputStream sis = con.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(sis);
            ByteArrayBuffer bab = new ByteArrayBuffer(32);
            int current = 0;
            while ((current = bis.read()) != -1) {
                bab.append((byte) current);
            }
            String result = EncodingUtils.getString(bab.toByteArray(), HTTP.UTF_8);
            JSONObject jsob = new JSONObject(result);
            if (jsob.getInt("error_code") == 200) {
                return true;
            }
            return false;
        } catch (ClientProtocolException e) {
            Logger.d(e);
        } catch (IOException e) {
            Logger.d(e);
        } catch (JSONException e) {
            Logger.d(e);
        }
        return false;
    }

    /**
     * Gets the url connection.
     * 
     * @param url
     *            the url
     * @return the url connection
     * @throws IOException
     *             Signals that an I/O exception has occurred.
     */
    private static URLConnection getUrlConnection(URL url) throws IOException {
        String authorization = (new BASE64Encoder()).encode((StaticInfo.mUsername + ":" + StaticInfo.mPassword)
                .getBytes());
        URLConnection con = url.openConnection();
        con.addRequestProperty("mtype", "Android");
        con.addRequestProperty("Authorization", "BASIC: " + authorization);
        return con;
    }

    /**
     * Gets the user info.
     * 
     * @param context
     *            the context
     * @param strUrl
     *            the str url
     * @return the user info
     */
    public static User getUserInfo(Context context, String strUrl) {
        try {
            URL url;
            url = new URL(strUrl);
            URLConnection con = getUrlConnection(url);
            InputStream sis = con.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(sis);
            ByteArrayBuffer bab = new ByteArrayBuffer(32);
            int current = 0;
            while ((current = bis.read()) != -1) {
                bab.append((byte) current);
            }
            String result = EncodingUtils.getString(bab.toByteArray(), HTTP.UTF_8);
            JSONObject jsob = new JSONObject(result);
            return new User(jsob.optJSONObject("user"));
        } catch (MalformedURLException e) {
            Logger.d(e);
        } catch (IOException e) {
            Logger.d(e);
            context.sendBroadcast(new Intent(NO_NET));
        } catch (JSONException e) {
            Logger.d(e);
        }
        return new User();
    }

    /**
     * Gets the users.
     * 
     * @param context
     *            the context
     * @param strUrl
     *            the str url
     * @return the users
     */
    public static List getUsers(Context context, String strUrl) {
        try {
            String result = getResult(context, strUrl);
            Log.d("weibo", result);
            JSONObject jsob = new JSONObject(result);
            JSONArray jsa = jsob.optJSONArray("users");
            List lst = new ArrayList();
            if (jsa != null) {
                for (int i = 0; i < jsa.length(); i++) {
                    lst.add(new User(jsa.optJSONObject(i)));
                }
            }
            return lst;
        } catch (JSONException e) {
            Logger.d(e);
        }
        return new ArrayList();
    }

    /**
     * Gets the topics.
     * 
     * @param context
     *            the context
     * @param strUrl
     *            the str url
     * @return the topics
     */
    public static List getTopics(Context context, String strUrl) {
        try {
            String result = getResult(context, strUrl);
            JSONObject jsob = new JSONObject(result);
            JSONArray jsa = jsob.optJSONArray("topics");
            List lst = new ArrayList();
            if (jsa != null) {
                for (int i = 0; i < jsa.length(); i++) {
                    lst.add(new Topic(jsa.optJSONObject(i)));
                }
            }
            return lst;
        } catch (JSONException e) {
            Logger.d(e);
        }
        return new ArrayList();
    }

    /**
     * Checks if is friend.
     * 
     * @param context
     *            the context
     * @param strUid
     *            the str uid
     * @return the jSON object
     */
    public static JSONObject isFriend(Context context, String strUid) {
        try {
            URL url = new URL(Constant.FRIENDSHIPS_SHOW + "?uid2=" + strUid);
            URLConnection con = getUrlConnection(url);
            InputStream sis = con.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(sis);
            ByteArrayBuffer bab = new ByteArrayBuffer(32);
            int current = 0;
            while ((current = bis.read()) != -1) {
                bab.append((byte) current);
            }
            String result = EncodingUtils.getString(bab.toByteArray(), HTTP.UTF_8);
            Log.d("weibo", result);
            JSONObject jsob = new JSONObject(result);
            System.out.println(result);
            return jsob;
        } catch (MalformedURLException e) {
            Logger.d(e);
        } catch (IOException e) {
            Logger.d(e);
            context.sendBroadcast(new Intent(NO_NET));
        } catch (JSONException e) {
            Logger.d(e);
        }
        return new JSONObject();
    }

    /**
     * Gets the comments.
     * 
     * @param context
     *            the context
     * @param strUrl
     *            the str url
     * @return the comments
     */
    public static List getComments(Context context, String strUrl) {
        try {
            String result = getResult(context, strUrl);
            Log.d("weibo", result);
            JSONObject jsob = new JSONObject(result);
            JSONArray jsa = jsob.optJSONArray("comments");
            List lst = new ArrayList();
            for (int i = 0; i < jsa.length(); i++) {
                lst.add(new Comment(jsa.optJSONObject(i)));
            }
            return lst;
        } catch (JSONException e) {
            Logger.d(e);
        }
        return new ArrayList();
    }

    /**
     * Gets the messages.
     * 
     * @param context
     *            the context
     * @param strUrl
     *            the str url
     * @return the messages
     */
    public static List getMessages(Context context, String strUrl) {
        try {
            String result = getResult(context, strUrl);
            JSONObject jsob = new JSONObject(result);
            JSONArray jsa = jsob.optJSONArray("messages");
            List lst = new ArrayList();
            for (int i = 0; i < jsa.length(); i++) {
                lst.add(new Message(jsa.optJSONObject(i)));
            }
            return lst;
        } catch (JSONException e) {
            Logger.d(e);
        }
        return new ArrayList();
    }

    /**
     * Gets the comment.
     * 
     * @param context
     *            the context
     * @param strUrl
     *            the str url
     * @return the comment
     */
    public static Comment getComment(Context context, String strUrl) {
        try {
            String result = getResult(context, strUrl);
            JSONObject jsob = new JSONObject(result);
            return new Comment(jsob.optJSONObject("comment"));
        } catch (JSONException e) {
            Logger.d(e);
        }
        return new Comment();
    }

    /**
     * Gets the result.
     * 
     * @param context
     *            the context
     * @param strUrl
     *            the str url
     * @return the result
     */
    private static String getResult(Context context, String strUrl) {
        try {
            URL url = new URL(strUrl);
            URLConnection con = getUrlConnection(url);
            InputStream sis = con.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(sis);
            ByteArrayBuffer bab = new ByteArrayBuffer(32);
            int current = 0;
            while ((current = bis.read()) != -1) {
                bab.append((byte) current);
            }
            String result = EncodingUtils.getString(bab.toByteArray(), HTTP.UTF_8);
            return result;
        } catch (MalformedURLException e) {
            Logger.d(e);
        } catch (IOException e) {
            Logger.d(e);
            context.sendBroadcast(new Intent(NO_NET));
        }
        return "";
    }

    /**
     * Gets the topic.
     * 
     * @param context
     *            the context
     * @param strUrl
     *            the str url
     * @return the topic
     */
    public static Topic getTopic(Context context, String strUrl) {
        try {
            String result = getResult(context, strUrl);
            JSONObject jsob = new JSONObject(result);
            return new Topic(jsob.optJSONObject("topic"));
        } catch (JSONException e) {
            Logger.d(e);
        }
        return new Topic();
    }

    /**
     * Post topic.
     * 
     * @param context
     *            the context
     * @param strUrl
     *            the str url
     * @param content
     *            the content
     * @param bitmap
     *            the bitmap
     * @return the topic
     */
    public static Topic postTopic(Context context, String strUrl, String content, Bitmap bitmap) {
        try {
            String BOUNDARY = "--------------et567z";
            String MULTIPART_FORM_DATA = "multipart/form-data";
            URL url = new URL(strUrl);
            HttpURLConnection con = (HttpURLConnection) getUrlConnection(url);
            con.setUseCaches(false);
            con.setDefaultUseCaches(false);
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setRequestMethod("POST");
            con.setRequestProperty("Connection", "Keep-Alive");
            con.setRequestProperty("Charset", "UTF-8");
            con.setRequestProperty("Content-Type", MULTIPART_FORM_DATA + ";boundary=" + BOUNDARY);
            ByteArrayOutputStream bao = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bao);
            byte[] ba = bao.toByteArray();
            StringBuilder sb = new StringBuilder();
            sb.append("--");
            sb.append(BOUNDARY);
            sb.append("\r\n");
            sb.append("Content-Disposition: form-data; name=\"contents\"\r\n\r\n");
            sb.append(content);
            sb.append("\r\n");
            DataOutputStream outStream = new DataOutputStream(con.getOutputStream());
            outStream.write(sb.toString().getBytes());
            StringBuilder split = new StringBuilder();
            split.append("--");
            split.append(BOUNDARY);
            split.append("\r\n");
            split.append("Content-Disposition: form-data;name=\"pic\";filename=\"temp.jpg\"\r\n");
            split.append("Content-Type: image/jpeg\r\n\r\n");
            outStream.write(split.toString().getBytes());
            outStream.write(ba, 0, ba.length);
            outStream.write("\r\n".getBytes());
            byte[] end_data = ("--" + BOUNDARY + "--\r\n").getBytes();
            outStream.write(end_data);
            outStream.flush();
            InputStream sis = con.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(sis);
            ByteArrayBuffer bab = new ByteArrayBuffer(32);
            int current = 0;
            while ((current = bis.read()) != -1) {
                bab.append((byte) current);
            }
            String result = EncodingUtils.getString(bab.toByteArray(), HTTP.UTF_8);
            JSONObject jsob = new JSONObject(result);
            return new Topic(jsob.optJSONObject("topic"));
        } catch (MalformedURLException e) {
            Logger.d(e);
        } catch (IOException e) {
            Logger.d(e);
            context.sendBroadcast(new Intent(NO_NET));
        } catch (JSONException e) {
            Logger.d(e);
        }
        return new Topic();
    }

    /**
     * Gets the image.
     * 
     * @param context
     *            the context
     * @param strUrl
     *            the str url
     * @return the image
     */
    public static Bitmap getImage(Context context, String strUrl) {
        HttpURLConnection conn;
        Bitmap bitmap = null;
        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.portrait);
        if (StaticInfo.map.containsKey(strUrl)) {
            return StaticInfo.map.get(strUrl);
        }
        String strMD5 = getMD5(strUrl);
        File localFile1 = Environment.getExternalStorageDirectory();
        File path = new File(localFile1.getPath() + File.separator + "zhiweibo/weibo");
        if (!path.exists()) {
            path.mkdirs();
        }
        File f = new File(path, strMD5);
        if (f.exists()) {
            bitmap = BitmapFactory.decodeFile(f.getPath());
        } else {
            try {
                URL url = new URL(strUrl);
                conn = (HttpURLConnection) getUrlConnection(url);
                conn.setDoInput(true);
                conn.connect();
                InputStream is = conn.getInputStream();
                bitmap = BitmapFactory.decodeStream(is);
                savePic(bitmap, f);
                is.close();
            } catch (Exception e) {
                Logger.d(e);
            }
        }
        if (strUrl.contains("face")) {
            bitmap = ImageUtil.getRoundedCornerBitmap(bitmap);
        }
        if (bitmap != BitmapFactory.decodeResource(context.getResources(), R.drawable.portrait)) {
            StaticInfo.map.put(strUrl, bitmap);
        }
        return bitmap;
    }

    /**
     * Save pic.
     * 
     * @param bitmap
     *            the bitmap
     * @param f
     *            the f
     * @throws FileNotFoundException
     *             the file not found exception
     * @throws IOException
     *             Signals that an I/O exception has occurred.
     */
    private synchronized static void savePic(Bitmap bitmap, File f) throws FileNotFoundException, IOException {
        FileOutputStream fOut = new FileOutputStream(f);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
        fOut.flush();
        fOut.close();
    }

    /**
     * Gets the m d5.
     * 
     * @param strUrl
     *            the str url
     * @return the m d5
     */
    private static String getMD5(String strUrl) {
        MessageDigest md;
        StringBuffer buf = new StringBuffer("");
        try {
            md = MessageDigest.getInstance("MD5");
            md.update(strUrl.getBytes());
            byte b[] = md.digest();
            int i;
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0) {
                    i += 256;
                }
                if (i < 16) {
                    buf.append("0");
                }
                buf.append(Integer.toHexString(i));
            }
        } catch (Exception e) {
            Logger.d(e);
        }
        return buf.toString();
    }

    /**
     * Gets the unread.
     * 
     * @return the unread
     */
    public static UnreadNum getUnread(String id) {
        try {
            URL url = new URL(Constant.UNREAD + "?with_new_status=1&since_id=" + id);
            URLConnection con = getUrlConnection(url);
            InputStream sis = con.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(sis);
            ByteArrayBuffer bab = new ByteArrayBuffer(32);
            int current = 0;
            while ((current = bis.read()) != -1) {
                bab.append((byte) current);
            }
            String result = EncodingUtils.getString(bab.toByteArray(), HTTP.UTF_8);
            Log.d("weibo", result);
            JSONObject jsob = new JSONObject(result);
            return new UnreadNum(jsob);
        } catch (Exception e) {
            Logger.d(e);
        }
        return new UnreadNum();
    }

    /**
     * Exe url.
     * 
     * @param context
     *            the context
     * @param strUrl
     *            the str url
     * @return the string
     */
    public static String exeUrl(Context context, String strUrl) {
        try {
            URL url = new URL(strUrl);
            URLConnection con = getUrlConnection(url);
            InputStream sis = con.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(sis);
            ByteArrayBuffer bab = new ByteArrayBuffer(32);
            int current = 0;
            while ((current = bis.read()) != -1) {
                bab.append((byte) current);
            }
            String result = EncodingUtils.getString(bab.toByteArray(), HTTP.UTF_8);
            Log.d("weibo", result);
            return result;
        } catch (MalformedURLException e) {
            Logger.d(e);
        } catch (IOException e) {
            Logger.d(e);
            context.sendBroadcast(new Intent(NO_NET));
        }
        return "";
    }

    /**
     * Del no.
     * 
     * @param strUrl
     *            the str url
     * @return the string
     */
    public static String delNo(String strUrl) {
        try {
            URL url = new URL(strUrl);
            URLConnection con = getUrlConnection(url);
            InputStream sis = con.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(sis);
            ByteArrayBuffer bab = new ByteArrayBuffer(32);
            int current = 0;
            while ((current = bis.read()) != -1) {
                bab.append((byte) current);
            }
            String result = EncodingUtils.getString(bab.toByteArray(), HTTP.UTF_8);
            Log.d("weibo", result);
            return result;
        } catch (Exception e) {
            Logger.d(e);
        }
        return "";
    }

    /**
     * Gets the counts.
     * 
     * @param strUrl
     *            the str url
     * @return the counts
     */
    private static Count getcounts(String strUrl) {
        try {
            URL url = new URL(strUrl);
            URLConnection con = getUrlConnection(url);
            InputStream sis = con.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(sis);
            ByteArrayBuffer bab = new ByteArrayBuffer(32);
            int current = 0;
            while ((current = bis.read()) != -1) {
                bab.append((byte) current);
            }
            String result = EncodingUtils.getString(bab.toByteArray(), HTTP.UTF_8);
            JSONObject jsob = new JSONObject(result);
            JSONArray jsa = jsob.optJSONArray("topics");
            if (jsa != null) {
                return new Count(jsa.optJSONObject(0));
            }
            Log.d("weibo", result);
        } catch (Exception e) {
            Logger.d(e);
        }
        return new Count();
    }

    /**
     * Gets the count.
     * 
     * @param tid
     *            the tid
     * @return the count
     */
    public static Count getcount(String tid) {
        return getcounts(Constant.COUNTS + "?tids=" + tid);
    }

    /**
     * Gets the version.
     * 
     * @return the version
     */
    public static String getVersion() {
        try {
            URL url = new URL("http://t.hrbanlv.com/download/version.txt");
            URLConnection con = url.openConnection();
            con.setConnectTimeout(10000);
            InputStream sis = con.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(sis);
            ByteArrayBuffer bab = new ByteArrayBuffer(32);
            int current = 0;
            while ((current = bis.read()) != -1) {
                bab.append((byte) current);
            }
            String result = EncodingUtils.getString(bab.toByteArray(), HTTP.UTF_8);
            Log.d("weibo", result);
            return result;
        } catch (Exception e) {
            Logger.d(e);
        }
        return "10000";
    }

}